package util.nlp;

import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedList;

import util.hashing.HashOperations;
import util.io.FileInput;

public class HierarchyHash {

	/**
	 * @param args
	 */

	private static Hashtable<String, LinkedList<String>> hierarchy = new Hashtable<String, LinkedList<String>>();

	private static Hashtable<String, LinkedList<String>> covered = new Hashtable<String, LinkedList<String>>();

	private Hashtable<String, LinkedList<String>> hierarchy_clusters = new Hashtable<String, LinkedList<String>>();

	private Hashtable<String, LinkedList<String>> covered_clusters = new Hashtable<String, LinkedList<String>>();

	public HierarchyHash(String path) {

		FileInput in = new FileInput(path);

		String line = in.readString();

		while (line != null) {

			line = line.trim();

			String t[] = line.split("\t");

			LinkedList<String> list = new LinkedList<String>();

			if (t != null) {

				LinkedList<String> l = new LinkedList<String>();

				hierarchy.put(t[0], l);
				covered.put(t[0], new LinkedList<String>());

				for (int i = t.length - 1; i > 0; i--) {

					HashOperations.updateHashOfList(hierarchy, t[i - 1], t[i],
							true);

					HashOperations.updateHashOfList(covered, t[i], t[i - 1],
							true);

				}

			}

			line = in.readString();
		}

	}

	/**
	 * Returns paths in the hierarchy that lead to the argument 'tag'
	 */

	public void getPaths(String tag, LinkedList<LinkedList<String>> paths) {

		if (paths == null)
			return;

		if (paths.size() < 1) {
			LinkedList<String> list = new LinkedList<String>();
			paths.add(list);

		}

		for (int i = 0; i < paths.size(); i++) {

			LinkedList<String> path = paths.get(i);
			path.addFirst(tag);

			// System.out.println(paths.size());

			if (covered.containsKey(tag)) {
				LinkedList<String> fathers = covered.get(tag);
				for (int j = 0; fathers != null && j < fathers.size(); j++) {

					getPaths(fathers.get(j), paths);

				}

			}

		}

	}

	public void generateClusters(Enumeration<String> enu) {

		while (enu.hasMoreElements()) {

			// get paths of current tag
			String tag = enu.nextElement();

			if (covered.containsKey(tag) || covered.contains(tag)
					|| hierarchy.containsKey(tag)) {

				LinkedList<LinkedList<String>> paths = new LinkedList<LinkedList<String>>();

				getPaths(tag, paths);

				// update hierarchy

				for (int i = 0; i < paths.size(); i++) {

					LinkedList<String> path = paths.get(i);
					// System.out.println(tag);
					for (int j = 0; j < path.size() - 1; j++) {

						HashOperations.updateHashOfList(hierarchy_clusters,
								path.get(j), path.get(j + 1), true);

						HashOperations.updateHashOfList(covered_clusters, path
								.get(j + 1), path.get(j), true);

					}

					if (path.size() - 1 >= 0)
						HashOperations.updateHashOfList(hierarchy_clusters,
								path.get(path.size() - 1), null, true);

				}

			}

		}

	}

	public void printHierarchy() {
		// Print hierarchy
		Enumeration<String> keys = hierarchy_clusters.keys();

		// for each key covered by nobody
		while (keys.hasMoreElements()) {

			String key = keys.nextElement();

			LinkedList<String> list;
			if (!covered_clusters.containsKey(key)) {

				System.out.println(key);
				list = hierarchy_clusters.get(key);

				for (int i = 0; i < list.size(); i++) {
					printHierarchyHelper(list.get(i), 1);

				}

			}

		}

	}

	public void printHierarchyInLine() {
		// Print hierarchy

		Enumeration<String> keys = hierarchy_clusters.keys();

		// for each key covered by nobody
		while (keys.hasMoreElements()) {

			String key = keys.nextElement();

			LinkedList<String> list;
			if (!covered_clusters.containsKey(key)) {

				String cat = key;
				list = hierarchy_clusters.get(key);

				for (int i = 0; i < list.size(); i++) {
					printHierarchyHelper2(cat, list.get(i), 1);

				}

			}

		}

	}

	public LinkedList<String> getHierarchyInLine() {
		// Print hierarchy

		LinkedList<String> results = new LinkedList<String>();

		Enumeration<String> keys = hierarchy_clusters.keys();

		// for each key covered by nobody
		while (keys.hasMoreElements()) {

			String key = keys.nextElement();

			LinkedList<String> list;
			if (!covered_clusters.containsKey(key)) {

				String cat = key;
				list = hierarchy_clusters.get(key);

				results.add(cat);
				for (int i = 0; i < list.size(); i++) {
					getHierarchyHelper2(cat, list.get(i), 1, results);

				}

			}

		}

		for (int i = 0; i < results.size(); i++) {

			// System.out.println(results.get(i));
		}

		return results;

	}

	public void printHierarchyHelper(String value, int level) {
		// Print hierarchy
		String indent = "\t";

		for (int i = 0; i < level; i++) {

			indent = indent + "\t";

		}

		System.out.println(indent + value);

		if (hierarchy_clusters.containsKey(value)) {

			LinkedList<String> list = hierarchy_clusters.get(value);

			for (int i = 0; i < list.size(); i++) {

				printHierarchyHelper(list.get(i), level + 1);

			}

		}

	}

	public String getJSONFromHierarchyLine(String line) {

		String l = "";
		String comi = "\"";

		String t[] = line.split("\t+");

		if (t.length == 1) {
			l = "\t" + comi + t[0] + comi;

		} else {
			String indent = "";
			for (int i = 0; i < t.length - 1; i++) {
				indent = "";

				for (int j = 1; j < i + 1; j++) {

					indent = indent + "\t";

				}

				l = l + indent + "[" + comi + t[i] + comi + "," + "\n";

			}

			l = l + indent + "\t[" + comi + t[t.length - 1] + comi + "\n";

			for (int i = t.length - 1; i > 0; i--) {
				indent = "";
				for (int j = i; j > 0; j--) {
					indent = indent + " \t";
				}
				l = l + indent + "]\n";

			}

			l = l + "]";

		}

		return l;
	}

	public void printHierarchyHelper2(String cat, String value, int level) {

		cat = cat + "\t" + value;
		System.out.println(cat);

		if (hierarchy_clusters.containsKey(value)) {

			LinkedList<String> list = hierarchy_clusters.get(value);

			for (int i = 0; i < list.size(); i++) {

				printHierarchyHelper2(cat, list.get(i), level + 1);

			}
		}
	}

	public void getHierarchyHelper2(String cat, String value, int level,
			LinkedList<String> lines) {

		cat = cat + "\t" + value;

		if (lines.size() > 0 && level > 0) {
			if (cat.startsWith(lines.get(lines.size() - 1))) {
				lines.remove(lines.size() - 1);
				lines.add(cat);

			} else {

				lines.add(cat);
			}

		} else {

			lines.add(cat);

		}

		// System.out.println(cat);

		if (hierarchy_clusters.containsKey(value)) {

			LinkedList<String> list = hierarchy_clusters.get(value);

			for (int i = 0; i < list.size(); i++) {

				getHierarchyHelper2(cat, list.get(i), level + 1, lines);

			}
		}
	}

	public void clean() {

		hierarchy_clusters.clear();
		covered_clusters.clear();

	}

	// 

	public String getJSONPost() {

		String post1 = "	\n";

		String post = "\t";
		Enumeration<String> keys = hierarchy_clusters.keys();

		LinkedList<String> list = getHierarchyInLine();

		for (int i = 0; i < list.size() - 1; i++) {

			String tmp = getJSONFromHierarchyLine(list.get(i));

			post = post + tmp + ",\n";

		}

		String tmp = getJSONFromHierarchyLine(list.get(list.size() - 1));

		post = post + tmp + "\n";

		post = post.replaceAll("\n", "\n\t");
		post = post.replaceAll("\\t+\"", "\t\"");

		post1 = post1 + post;

		post1 = post1 + "]\n}";
		// for each key covered by nobody

		return post1;
	}

	
	public String getJSONPostCondensed(String query) {

		String post = "[" + "\"" + query + "\"," + "\n";

	

		LinkedList<String> list = getHierarchyInLine();

		for (int i = 0; i < list.size(); i++) {

			String tmp[] = list.get(i).split("\t");

			post = post + "[";
			for (int j = 0; j < tmp.length - 1; j++) {

				post = post + "\"" + tmp[j] + "\"" + ",[";
			}

			post = post + "\"" + tmp[tmp.length - 1] + "\"" + "]";
			
			
			for (int j = 0; j < tmp.length-1; j++) {
				post = post + "]";

			}

			
			if(i<list.size()-1)
			post = post + ",\n";

		}
		post = post + "\n]";
		
		
		
		return post;
	}
	public void printJSONHelper(String value, int level, String post) {
		// Print hierarchy
		String indent = "\t";

		for (int i = 0; i < level; i++) {

			indent = indent + "\t";

		}

		post = post + indent + value + " :[{\n";

		if (hierarchy_clusters.containsKey(value)) {

			LinkedList<String> list = hierarchy_clusters.get(value);

			for (int i = 0; i < list.size(); i++) {

				printHierarchyHelper(list.get(i), level + 1);

			}

		}

		post = post + indent + "} ],\n";

	}

	
	
	public static void printTags (String path) {

		FileInput in = new FileInput(path);

		String line = in.readString();

		while (line != null) {

			line = line.trim();

			String t[] = line.split("\t");

			for(int i =4 ; i < t.length; i++){
				System.out.println(t[i]);
				
			}

			line = in.readString();
		}

	}

	
	public static void printTagsFreq (String path, int tr) {

		FileInput in = new FileInput(path);

		String line = in.readString();
		Hashtable<String,Integer> hash = new Hashtable<String,Integer>();

		while (line != null) {

			line = line.trim();

			String t[] = line.split("\t");

			for(int i =4 ; i < t.length; i++){
				
				if(hash.contains(t[i])){
					hash.put(t[i], hash.get(t[i])+1);
					
				}else{
					hash.put(t[i], 1);
					
				}	
				
				System.out.println(t[i]);
				
			}

			line = in.readString();
		}
		
		
		Enumeration<String> keys = hash.keys();
		
		while(keys.hasMoreElements()){
			
			
			String key= keys.nextElement();
			System.out.println(key);
			if(hash.get(key)> tr)
				System.out.println(key + "\t"+ hash.get(key));
		}

	}
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		/*HashSet<String> set = new HashSet<String>();

		String path = "";

		path = "/home/sergio/Documents/delicious_stats/tag_hierarchy.txt";
		Hashtable<String, String> hash = new Hashtable<String, String>();

		hash.put("technology", "");
		hash.put("reading", "");
		hash.put("preschool", "");
		hash.put("elmo", "");
		hash.put("videos", "");
		hash.put("technology", "");
		hash.put("learning", "");

		set.add("technology");
		set.add("kids");

		set.add("learning");
		set.add("preschool");
		set.add("reading");
		set.add("elmo");
		set.add("videos");
		set.add("games");
		set.add("fisherprice");
		set.add("toys");

		HierarchyHash h = new HierarchyHash(path);
		h.generateClusters(hash.keys());

		// System.out.println(h.printJSONPost());
		System.out.println("--------------------");
		String line = "pre-school	television	sesame_street	elmo";

		h.getHierarchyInLine();
		System.out.println("--------------------");
		System.out.println(h.getJSONPost());
		h.printHierarchyInLine();*/
		
		String path = "/media/sata/data/delicious/hierarchy_data.txt";
		path = "/media/sata/data/delicious/delicious_single_kids_cleaned.txt";
	//	printTags(path);
		 printTagsFreq(path,10);
		// System.out.println(h.getJSONFromHierarchyLine(line));

	}

}
